package com.lxf.cn.web;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lxf.cn.elasticsearch.page.EsPage;
import com.lxf.cn.elasticsearch.uitl.ElasticsearchUtil;
import javafx.scene.chart.BubbleChart;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;



/**
 * Created by liaoxuefeng on 2018/11/12.
 */


@RestController
@RequestMapping("/es")
public class ElasticSearchController {


    @Autowired
    ElasticsearchUtil elasticsearchUtil ;

    /**
     * 测试索引
     */
    private String indexName = "test_index";

    /**
     * 类型
     */
    private String esType = "external";


    /**
     * http://127.0.0.1:8080/es/createIndex
     * 创建索引
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/createIndex")
    @ResponseBody
    public String createIndex(HttpServletRequest request, HttpServletResponse response ) {
        if (!ElasticsearchUtil.isIndexExist( indexName)) {
            ElasticsearchUtil.createIndex( indexName);
        } else {
            return "索引已经存在";
        }
        return "索引创建成功";
    }


    /**
     * 删除索引
     *
     * @return
     */
    @RequestMapping("/deleteIndex")
    public
    @ResponseBody
    String deleteIndex(HttpServletRequest request, HttpServletResponse response) {

        for (int i = 1 ; i <= 100000 ; i++){
            ElasticsearchUtil.deleteIndex( String.valueOf(i));
        }

        return "删除成功";
    }


    /**
     * 创建mapping
     *
     * @return
     */
    @RequestMapping("/createBangMapping")
    @ResponseBody
    public String createBangMapping() {
        return elasticsearchUtil.createBangMapping(indexName , esType);
    }


    /**
     * 插入记录
     *
     * @return
     */
    @RequestMapping(value = "/insertJson", method = RequestMethod.POST)
    @ResponseBody
    public String insertJson(@RequestBody JSONObject params) {
        for (int i = 1  ; i <=100  ; i++){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", i); //可以不要
            jsonObject.put("age", params.getInteger("age")+i);
            jsonObject.put("name", params.getString("name")+i);
            jsonObject.put("date", params.getString("date"));
            jsonObject.put("content", params.getString("content")+i);
            jsonObject.put("userType", params.getString("userType")+i);
            elasticsearchUtil.addData(jsonObject, indexName, esType, jsonObject.getString("id"));
            System.out.println("第'"+i+"'数据"+i);
        }
        return "操作成功添加2万数据";
    }


    /**
     * 大数据插入
     * @param params
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/insert/big/Json" , method = RequestMethod.POST)
    @ResponseBody
    public  String bigJson(@RequestBody JSONObject params) {
        try {
            return elasticsearchUtil.bigDate(indexName ,esType );
        }catch (Exception e){

            e.printStackTrace();
            return "插入失败!";
        }
    }

    /**
     * 插入记录
     *
     * @return
     */
    @RequestMapping("/insertModel")
    @ResponseBody
    public String insertModel() {
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(new JSONObject());
        return ElasticsearchUtil.addData( jsonObject, indexName, esType, jsonObject.getString("id"));
    }

    /**
     * 删除记录
     *
     * @return
     */
    @RequestMapping("/delete")
    @ResponseBody
    public String delete(String id) {
        if (StringUtils.isNotBlank(id)) {
            ElasticsearchUtil.deleteDataById( indexName, esType, id);
            return "删除id=" + id;
        } else {
            return "id为空";
        }
    }

    /**
     * 更新数据
     *
     * @return
     */
    @RequestMapping("/update")
    @ResponseBody
    public String update(String id) {
        if (StringUtils.isNotBlank(id)) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", id);

            jsonObject.put("age", 31);

            ElasticsearchUtil.updateDataById( jsonObject, indexName, esType, id);
            return "id=" + id;
        } else {
            return "id为空";
        }
    }

    /**
     * 获取数据
     * http://127.0.0.1:8080/es/getData?id=2018-04-25%2016:33:44
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/getData")
    @ResponseBody
    public String getData(String id) {
        if (StringUtils.isNotBlank(id)) {
            Map<String, Object> map = ElasticsearchUtil.searchDataById( indexName, esType, id, null);
            return JSONObject.toJSONString(map);
        } else {
            return "id为空";
        }
    }

    /**
     * 查询数据
     * 模糊查询
     *
     * @return
     */
    @RequestMapping("/queryMatchData")
    @ResponseBody
    public String queryMatchData() {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolean matchPhrase = false;


        if (matchPhrase == Boolean.TRUE) {
            boolQuery.must(QueryBuilders.matchPhraseQuery("name", "修"));
        } else {
            boolQuery.must(QueryBuilders.matchQuery("name", "修"));
        }


        List<Map<String, Object>> list = ElasticsearchUtil.searchListData( indexName, esType, boolQuery, 10, null, null, null);
        return JSONObject.toJSONString(list);
    }

    /**
     * 通配符查询数据
     * 通配符查询 ?用来匹配1个任意字符，*用来匹配零个或者多个字符
     *
     * @return
     */
    @RequestMapping("/queryWildcardData")
    @ResponseBody
    public String queryWildcardData() {
        QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("name.keyword", "j-*466");
        List<Map<String, Object>> list = ElasticsearchUtil.searchListData( indexName, esType, queryBuilder, 10, null, null, null);
        return JSONObject.toJSONString(list);
    }

    /**
     * 正则查询
     *
     * @return
     */
    @RequestMapping("/queryRegexpData")
    @ResponseBody
    public String queryRegexpData() {
        QueryBuilder queryBuilder = QueryBuilders.regexpQuery("name.keyword", "j--[0-9]{1,11}");
        List<Map<String, Object>> list = ElasticsearchUtil.searchListData(indexName, esType, queryBuilder, 10, null, null, null);
        return JSONObject.toJSONString(list);
    }

    /**
     * 查询数字范围数据
     *
     * @return
     */
    @RequestMapping("/queryIntRangeData")
    @ResponseBody
    public String queryIntRangeData() {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.rangeQuery("age").from(1)
                .to(30));
        List<Map<String, Object>> list = ElasticsearchUtil.searchListData( indexName, esType, boolQuery, 10, null, null, null);
        return JSONObject.toJSONString(list);
    }

    /**
     * 查询日期范围数据
     *
     * @return
     */
    @RequestMapping("/queryDateRangeData")
    @ResponseBody
    public String queryDateRangeData() {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.rangeQuery("date").from("2018-11-10 00:00:00").to("2018-11-12 00:00:00"));
        List<Map<String, Object>> list = ElasticsearchUtil.searchListData( indexName, esType, boolQuery, 10, null, null, null);
        return JSONObject.toJSONString(list);
    }

    /**
     * 查询分页
     *
     * @param startPage 第几条记录开始
     *                  从0开始
     *                  第1页 ：http://127.0.0.1:8080/es/queryPage?startPage=0&pageSize=2
     *                 第2页 ：http://127.0.0.1:8080/es/queryPage?startPage=2&pageSize=2
     *
     *                  第3页 ： http://127.0.0.1:8080/es/queryPage?startPage=4&pageSize=2
     * @param pageSize  每页大小
     * @return
     *
     * (index-1) * pageSize ， pageSize
     *
     * 0 ， 2
     *
     * 2 ， 2
     *
     * 4 ， 2
     *
     * 6 ， 2
     *
     *
     */
    @RequestMapping("/queryPage")
    @ResponseBody
    public Object queryPage(String startPage, String pageSize) {
        long start = System.currentTimeMillis();

        if (StringUtils.isNotBlank(startPage) && StringUtils.isNotBlank(pageSize)) {
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();





         //   String pageFrom =  Integer.parseInt(startPage) <= 1 ? String.valueOf(0) : String.valueOf((Integer.parseInt(startPage) - 1) * Integer.parseInt(pageSize) ) ;

//            boolQuery.must(QueryBuilders.rangeQuery("date").from("2018-04-25T08:33:44.840Z")
//                    .to("2018-04-25T10:03:08.081Z"));

            //大于等于
            //  boolQuery.must(QueryBuilders.rangeQuery("date").gte("2018-11-21 00:00:01"));
            // 小于等于
            // boolQuery.must(QueryBuilders.rangeQuery("date").gte("2019-11-21 00:00:01"));


            //大于
            //  QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("fieldName").gt("fieldValue");
            //大于等于
            //  QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("fieldName").gte("fieldValue");
            //小于
            //  QueryBuilder queryBuilder4 = QueryBuilders.rangeQuery("fieldName").lt("fieldValue");
            //小于等于
            //  QueryBuilder queryBuilder5 = QueryBuilders.rangeQuery("fieldName").lte("fieldValue");

            //分词查询 需要创建mapping 分词 text
            //boolQuery.must(QueryBuilders.matchQuery("name","张三1"));  // and


            boolQuery.must(QueryBuilders.matchQuery("content","真"));  // and

           // boolQuery.should(QueryBuilders.matchQuery("name", "张三1")); // or
           // boolQuery.should(QueryBuilders.matchQuery("name", "李六2"));

           //  boolQuery.mustNot(QueryBuilders.existsQuery("age")); //null
           // boolQuery.must(QueryBuilders.existsQuery("name")); //not null


          //  QueryBuilders.termQuery("fieldName").gt;


            //highlightField 必须配合字段不为null的情况下使用
            EsPage list = ElasticsearchUtil.searchDataPage( indexName, esType,  Integer.parseInt(startPage ) ,  Integer.parseInt(pageSize), boolQuery, null, "id", null);
            long end = System.currentTimeMillis();
            System.out.printf("result"+(end-start));

            return list;
        } else {
            return "startPage或者pageSize缺失";
        }
    }

}

